/*************************************************************************
*                              起源太空
*
*------------------------------------------------------------------------
* 文件名：		ps_uart.c
* 使用说明：	用于ps端uart通信
*------------------------------------------------------------------------
* 日期： 		2022.10.28
* 版本： 		V0.0
* 修改人：		XXX
* 修改内容：  	创建
*------------------------------------------------------------------------
* 					修改 / 更新记录
*------------------------------------------------------------------------
* 日期： 		xxxx.xx.xx
* 版本： 		V0.1
* 修改人：		XXX
* 修改内容：	1.添加了XXX XXX 功能
*            	2.修改了XXX XXX 的错误
*------------------------------------------------------------------------
* 日期： 		xxxx.xx.xx
* 版本： 		V0.2
* 修改人：		XXX
* 修改内容：	1.添加了XXX XXX 功能
*            	2.修改了XXX XXX 的错误
*************************************************************************/



/*************************************************************************
*                               头文件
*************************************************************************/
#include <stdlib.h>
#include <stdio.h>

#include "sleep.h"
#include "dri_hal_uart.h"

/*************************************************************************
*                           全局变量 \ 引用
*************************************************************************/



/*************************************************************************
*                           本地变量 \ 引用
*************************************************************************/
static volatile int TotalReceivedCount;
static volatile int TotalSentCount;
static int TotalErrorCount;

//static u8 SendBuffer[BUFFER_SIZE];	/* 发送数据数组  */
static u8 RecvBuffer[BUFFER_SIZE];	/* 接收数据数组 */


static int SetupInterruptSystem(INTC *IntcInstancePtr,
		XUartPs *UartInstancePtr, u16 usUartIntrId);

void PsUartHandler_0(void *CallBackRef, u32 Event, unsigned int EventData);
void PsUartHandler_1(void *CallBackRef, u32 Event, unsigned int EventData);
/*************************************************************************
* 函数名称：	UartPsIntrInit
* 功能：		初始化ps端的uart端口
**************************************************************************
* 输入变量：
* 			IntcInstPtr			系统中断设备指针
* 			UartInstPtr			ps端uart设备的指针
* 			usDeviceId			uart设备号
* 			usUartIntrId		uart中断号
* 输出变量：		无
* 返回值：		iStatus:
* 				XST_SUCCESS		0		成功
* 				XST_FAILURE		1		失败
*-----------------------------------------------------------------------
* 日期          		修改人        		修改内容
*-----------------------------------------------------------------------
* 2022.10.28           张海峰          		创建
* xxxx.xx.xx    XXX          添加/修改了XXXXXXXXXXX
*************************************************************************/
int UartPsIntrInit(INTC *IntcInstPtr, XUartPs *UartInstPtr,
			u16 usDeviceId, u16 usUartIntrId)
{
	int iStatus = XST_FAILURE;
	XUartPs_Config *Config;
	int iIndex;
	u32 IntrMask;

	/* 初始化uart驱动  */
	Config = XUartPs_LookupConfig(usDeviceId);
	if (NULL == Config)
	{
		return XST_FAILURE;
	}

	iStatus = XUartPs_CfgInitialize(UartInstPtr, Config, Config->BaseAddress);
	if (iStatus != XST_SUCCESS)
	{
		return XST_FAILURE;
	}

	/* 检测硬件设备 */
	iStatus = XUartPs_SelfTest(UartInstPtr);
	if (iStatus != XST_SUCCESS)
	{
		return XST_FAILURE;
	}

	/* 配置系统中断  */
	iStatus = SetupInterruptSystem(IntcInstPtr, UartInstPtr, usUartIntrId);
	if (iStatus != XST_SUCCESS)
	{
		return XST_FAILURE;
	}

	/* 设置uart的中断处理函数  */
	if (XPAR_XUARTPS_0_DEVICE_ID == usDeviceId)
	{
		XUartPs_SetHandler(UartInstPtr, (XUartPs_Handler)PsUartHandler_0, UartInstPtr);
	}
	else
	{
		XUartPs_SetHandler(UartInstPtr, (XUartPs_Handler)PsUartHandler_1, UartInstPtr);
	}

	/* 设置uart的中断配置  */
	IntrMask =
		XUARTPS_IXR_TOUT | XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING |
		XUARTPS_IXR_OVER | XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXFULL |
		XUARTPS_IXR_RXOVR;
#if 0
	if (UartInstPtr->Platform == XPLAT_ZYNQ_ULTRA_MP) {
		IntrMask |= XUARTPS_IXR_RBRK;
	}
#endif
	XUartPs_SetInterruptMask(UartInstPtr, IntrMask);
	XUartPs_SetOperMode(UartInstPtr, XUARTPS_OPER_MODE_NORMAL);

	XUartPs_SetFifoThreshold(UartInstPtr, 1);

	/* 设置uart接收超时时间  */
	//XUartPs_SetRecvTimeout(UartInstPtr, 8);

	/* 清空接收数组  */
	for (iIndex = 0; iIndex < BUFFER_SIZE; iIndex++)
	{
		//SendBuffer[iIndex] = (iIndex % 26) + 'A';
		RecvBuffer[iIndex] = 0;
	}

	return XST_SUCCESS;
}


void PsUartHandler_0(void *CallBackRef, u32 Event, unsigned int EventData)
{
	/* 全部发送 */
	if (Event == XUARTPS_EVENT_SENT_DATA) {
		TotalSentCount = EventData;
	}

	/* 全部接收 */
	if (Event == XUARTPS_EVENT_RECV_DATA) {
		TotalReceivedCount = EventData;
		//ChangeModeMsgProcess();
		//memset(LittleFpgaRecvBuff, 0, sizeof(LittleFpgaRecvBuff));
	}
#if 0
	else
	{
		int iIndex = 0;

		ChangeModeMsgProcess();

		memset(LittleFpgaRecvBuff, 0, sizeof(LittleFpgaRecvBuff));

		XUartPs_Recv(&UartPs_0, LittleFpgaRecvBuff, sizeof(LittleFpgaRecvBuff));

	}
#endif


}

/*************************************************************************
* 函数名称：	PsUartHandler
* 功能：		处理ps端uart的中断
**************************************************************************
* 输入变量：
* 			CallBackRef,			回调函数指针
* 			Event,					中断事件编号
* 			EventData				事件的字节数
* 输出变量：		无
* 返回值：			无
*-----------------------------------------------------------------------
* 日期          		修改人        		修改内容
*-----------------------------------------------------------------------
* 2022.10.28           张海峰          		创建
* xxxx.xx.xx    XXX          添加/修改了XXXXXXXXXXX
*************************************************************************/
void PsUartHandler_1(void *CallBackRef, u32 Event, unsigned int EventData)
{
	/* 全部发送 */
	if (Event == XUARTPS_EVENT_SENT_DATA) {
		TotalSentCount = EventData;
	}

	/* 全部接收 */
	if (Event == XUARTPS_EVENT_RECV_DATA) {
		TotalReceivedCount = EventData;
		memset(RecvBuffer, 0, sizeof(RecvBuffer));
	}

	/* 接收超时  */
	if (Event == XUARTPS_EVENT_RECV_TOUT) {
		TotalReceivedCount = EventData;
	}

	/* 接收错误   */
	if (Event == XUARTPS_EVENT_RECV_ERROR) {
		TotalReceivedCount = EventData;
		TotalErrorCount++;
	}

	/* 奇偶校验错误或中断错误  */
	if (Event == XUARTPS_EVENT_PARE_FRAME_BRKE) {
		TotalReceivedCount = EventData;
		TotalErrorCount++;
	}

	/* 接收校验错误 */
	if (Event == XUARTPS_EVENT_RECV_ORERR) {
		TotalReceivedCount = EventData;
		TotalErrorCount++;
	}
}

/*************************************************************************
* 函数名称：	SetupInterruptSystem
* 功能：		设置系统中断
**************************************************************************
* 输入变量：
* 			IntcInstancePtr			系统中断设备指针
* 			UartInstancePtr			ps端uart设备的指针
* 			usUartIntrId			uart中断号
* 输出变量：		无
* 返回值：		iStatus:
* 				XST_SUCCESS		0		成功
* 				XST_FAILURE		1		失败
*-----------------------------------------------------------------------
* 日期          		修改人        		修改内容
*-----------------------------------------------------------------------
* 2022.10.28           张海峰          		创建
* xxxx.xx.xx    XXX          添加/修改了XXXXXXXXXXX
*************************************************************************/
static int SetupInterruptSystem(INTC *IntcInstancePtr,
				XUartPs *UartInstancePtr, u16 usUartIntrId)
{
	int iStatus;

	/* 系统中断寄存器指针  */
	XScuGic_Config *IntcConfig;

	/* 初始化系统中断驱动  */
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfig) {
		return XST_FAILURE;
	}

	iStatus = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
					IntcConfig->CpuBaseAddress);
	if (iStatus != XST_SUCCESS)
	{
		return XST_FAILURE;
	}

	/* 配置ps端uart的中断处理函数  */
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
				(Xil_ExceptionHandler) XScuGic_InterruptHandler,
				IntcInstancePtr);

	iStatus = XScuGic_Connect(IntcInstancePtr, usUartIntrId,
				  (Xil_ExceptionHandler) XUartPs_InterruptHandler,
				  (void *) UartInstancePtr);
	if (iStatus != XST_SUCCESS)
	{
		return XST_FAILURE;
	}

	/* 配置ps端uart的中断号 */
	XScuGic_Enable(IntcInstancePtr, usUartIntrId);

	/* 使能中断  */
	 Xil_ExceptionEnable();

	return XST_SUCCESS;
}


/*************************************************************************
* 函数名称：	xil_scanf
* 功能：		ps端uart的格式化输入
**************************************************************************
* 输入变量：
* 			pcBuf			字符串指针
* 			iNBytes			接收的字符串的字节数
* 输出变量：		无
* 返回值：			无
*-----------------------------------------------------------------------
* 日期          		修改人        		修改内容
*-----------------------------------------------------------------------
* 2022.10.28           张海峰          		创建
* xxxx.xx.xx    XXX          添加/修改了XXXXXXXXXXX
*************************************************************************/
void xil_scanf (char8* pcBuf, s32 iNBytes)
{
#ifdef STDIN_BASEADDRESS
  s32 i;
  char8* LocalBuf = pcBuf;

  if(LocalBuf != NULL)
  {
	for (i = 0; i < iNBytes; i++)
	{
		*(LocalBuf + i) = inbyte();
		if ((*(LocalBuf + i) == '\n' )|| (*(LocalBuf + i) == '\r'))
		{
			LocalBuf = NULL;
			break;
		}
	}
  }
#endif
}





